package top.zy.service.zymallgoodsservice.goods.service;

import com.github.pagehelper.PageHelper;
import org.bouncycastle.asn1.x509.V2TBSCertListGenerator;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import top.zy.common.zymallcommon.utils.constants.CacheConstants;
import top.zy.common.zymallcommon.utils.exception.ZymalException;
import top.zy.common.zymallcommon.vo.PageResult;
import top.zy.service.zymallgoodsinterface.dto.GoodsPageParam;
import top.zy.service.zymallgoodsinterface.dto.GoodsParams;
import top.zy.service.zymallgoodsinterface.dto.SpuParam;
import top.zy.service.zymallgoodsinterface.entity.*;
import top.zy.service.zymallgoodsinterface.vo.GoodsVo;
import top.zy.service.zymallgoodsinterface.vo.SkuVo;
import top.zy.service.zymallgoodsservice.brand.dao.BrandMapper;
import top.zy.service.zymallgoodsservice.category.dao.CategoryMapper;
import top.zy.service.zymallgoodsservice.goods.dao.SkuMapper;
import top.zy.service.zymallgoodsservice.goods.dao.SpuDetailMapper;
import top.zy.service.zymallgoodsservice.goods.dao.SpuMapper;
import top.zy.service.zymallgoodsservice.goods.dao.StockMapper;
import top.zy.service.zymallgoodsservice.mq.SendMessageService;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @Author: HouZeYu
 * @Description:
 * @Date: Created in 15:50 2019/6/25
 */
@Service
public class GoodsServiceImpl implements GoodsService {


    private static final String SEND_QUEUE_DELETE_TYPE = "delete";

    private static final String SEND_QUEUE_INSERT_TYPE = "insert";

    private static final String SEND_QUEUE_UPDATE_TYPE = "update";
    @Autowired
    private SpuMapper spuMapper;

    @Autowired
    private SpuDetailMapper spuDetailMapper;

    @Autowired
    private SkuMapper skuMapper;

    @Autowired
    private CategoryMapper categoryMapper;

    @Autowired
    private BrandMapper brandMapper;


    @Autowired
    private StockMapper stockMapper;

    @Autowired
    private SendMessageService  sendMessageService;

    @Cacheable(value = CacheConstants.CACHE_GOODS_PAGE)
    @Override
    public PageResult<GoodsVo> queryGoodsPage(GoodsPageParam goodsPageParam) {
        if (goodsPageParam.getPage()==null){
            goodsPageParam.setPage(1);
        }
        if (goodsPageParam.getRows()==null){
            goodsPageParam.setRows(5);
        }
        if (goodsPageParam.getKey()!=null){
            goodsPageParam.setKey(goodsPageParam.getKey().toUpperCase());
        }
        PageHelper.startPage(goodsPageParam.getPage(),goodsPageParam.getRows());
        List<Spu> spuList=spuMapper.selectPageBySearchAndSaleEnable(goodsPageParam.getKey(),goodsPageParam.getSaleable());
        List<GoodsVo> goodsVoList=new ArrayList<>();
        if (!CollectionUtils.isEmpty(spuList))
        {
            spuList.stream().forEach(spu -> {
             GoodsVo goodsVo=new GoodsVo();
             BeanUtils.copyProperties(spu,goodsVo);
             Category category1= categoryMapper.selectByPrimaryKey(spu.getCid1());
             Category category2=categoryMapper.selectByPrimaryKey(spu.getCid2());
             Category category3=categoryMapper.selectByPrimaryKey(spu.getCid3());
             goodsVo.setCname(category1.getName()+'/'+category2.getName()+'/'+category3.getName());
              Brand brand= brandMapper.selectByPrimaryKey(spu.getBrandId());
              goodsVo.setBname(brand.getName());
              goodsVoList.add(goodsVo);
            });
        }
        PageResult pageResult=new PageResult();
     int count=spuMapper.selectCountBySearchAndSaleEnable(goodsPageParam.getKey(),goodsPageParam.getSaleable());
     pageResult.setTotal(Long.valueOf(count));
     pageResult.setItems(goodsVoList);
        return pageResult;
    }

    @Override
    public void saleableGoods(SpuParam spuParam) {
        Spu spu=new Spu();
        spu.setId(spuParam.getId());
        spu.setSaleable(spuParam.getSaleable());
      int result=spuMapper.updateByPrimaryKeySelective(spu);
      if (result==0){
          throw new ZymalException("上下架商品失败");
      }
      if (spu.getSaleable()){
           //发送新增商品消息
          sendMessageService.sendMessageToQueue(spu.getId(),SEND_QUEUE_INSERT_TYPE);
      }else {
          //发送删除商品消息
          sendMessageService.sendMessageToQueue(spu.getId(),SEND_QUEUE_DELETE_TYPE);
      }
    }

    @Override
    @Transactional
    public void deleteGoods(Long id) {
     List<Sku> skuList=skuMapper.selectSkuBySpuId(id);
     int result= spuMapper.deleteByPrimaryKey(id);
     if (result==0){
         throw new ZymalException("删除SPU表失败");
     }
        result=spuDetailMapper.deleteByPrimaryKey(id);
        if (result==0){
            throw new ZymalException("删除SPU详情表失败");
        }
        if (!CollectionUtils.isEmpty(skuList)){
           skuList.stream().forEach(sku -> {
            int  skuResult= skuMapper.deleteByPrimaryKey(sku.getId());
               if (skuResult==0){
                   throw new ZymalException("删除SKU表失败");
               }
               skuResult=stockMapper.deleteByPrimaryKey(sku.getId());
               if (skuResult==0){
                   throw new ZymalException("删除Stock表失败");
               }
           });
        }
        //发送删除商品消息
        sendMessageService.sendMessageToQueue(id,SEND_QUEUE_DELETE_TYPE);
    }

    @Transactional
    @Override
    public void saveGoods(GoodsParams goodsParams) {
         Spu spu=new Spu();
         BeanUtils.copyProperties(goodsParams,spu);
         spu.setCreateTime(new Date());
         spu.setLastUpdateTime(new Date());
        int result=spuMapper.insertSelective(spu);
        if (result==0){
            throw new ZymalException("spu表插入失败");
        }
        if (!CollectionUtils.isEmpty(goodsParams.getSkus())) {
            goodsParams.getSkus().stream().forEach(skuParam -> {
                Sku sku=new Sku();
                BeanUtils.copyProperties(skuParam,sku);
                sku.setCreateTime(new Date());
                sku.setLastUpdateTime(new Date());
                sku.setSpuId(spu.getId());
              int skuResult=skuMapper.insertSelective(sku);
                if (skuResult==0){
                    throw new ZymalException("sku表插入失败");
                }
                    Stock stock=new Stock();
                    stock.setSkuId(sku.getId());
                    stock.setStock(sku.getStock());
                    int stockResult=stockMapper.insertSelective(stock);
                    if (stockResult==0){
                        throw new ZymalException("stock表插入失败");
                    }
            });
           }
           goodsParams.getSpuDetail().setSpuId(spu.getId());
         result=spuDetailMapper.insert(goodsParams.getSpuDetail());
        if (result==0){
            throw new ZymalException("spuDetail表插入失败");
        }
        //发送新增商品消息
        sendMessageService.sendMessageToQueue(spu.getId(),SEND_QUEUE_INSERT_TYPE);
    }


    @Cacheable(value = CacheConstants.CACHE_GOODS_DETAIL_ID,key = "#p0")
    @Override
    public SpuDetail querySpuDetailById(Long spuId) {
        return spuDetailMapper.selectByPrimaryKey(spuId);
    }
    @Cacheable(value = CacheConstants.CACHE_GOODS_SKU_ID,key = "#p0")
    @Override
    @Transactional
    public List<SkuVo> querySkuBySpuId(Long spuId) {
       List<Sku> skuList= skuMapper.selectSkuBySpuId(spuId);
       List<SkuVo> skuVoList=new ArrayList<>();
       if (!CollectionUtils.isEmpty(skuList)){
           skuList.stream().forEach(sku -> {
               SkuVo skuVo=new SkuVo();
               BeanUtils.copyProperties(sku,skuVo);
               Stock stock= stockMapper.selectByPrimaryKey(sku.getId());
               skuVo.setStock(stock.getStock());
               skuVoList.add(skuVo);
           });
       }
        return skuVoList;
    }

    @Override
    @Transactional
    public void updateGoods(GoodsParams goodsParams) {
        Spu spu=new Spu();
        BeanUtils.copyProperties(goodsParams,spu);
        spu.setLastUpdateTime(new Date());
      int result=spuMapper.updateByPrimaryKeySelective(spu);
      if (result==0){
          throw new ZymalException("spu表更新失败");
      }
        if (!CollectionUtils.isEmpty(goodsParams.getSkus())) {
            goodsParams.getSkus().stream().forEach(skuParam -> {
                Sku sku=new Sku();
                BeanUtils.copyProperties(skuParam,sku);
                sku.setCreateTime(new Date());
                sku.setLastUpdateTime(new Date());
                sku.setSpuId(spu.getId());
                int skuResult;
                if (sku.getId()!=null){
                     skuResult=skuMapper.updateByPrimaryKeySelective(sku);
                    if (skuResult==0){
                        throw new ZymalException("sku表更新失败");
                    }
                        Stock stock=new Stock();
                        stock.setSkuId(sku.getId());
                        stock.setStock(sku.getStock());
                        int stockResult=stockMapper.updateByPrimaryKeySelective(stock);
                        if (stockResult==0){
                            throw new ZymalException("stock表更新失败");
                        }
                }else {
                    skuResult=skuMapper.insertSelective(sku);
                    if (skuResult==0){
                        throw new ZymalException("sku表插入失败");
                    }
                        Stock stock=new Stock();
                        stock.setSkuId(sku.getId());
                        stock.setStock(sku.getStock());
                        int stockResult=stockMapper.insertSelective(stock);
                        if (stockResult==0){
                            throw new ZymalException("stock表插入失败");
                        }
                }
            });
        }
        result=spuDetailMapper.updateByPrimaryKeySelective(goodsParams.getSpuDetail());
        if (result==0){
            throw new ZymalException("spuDetail表更新失败");
        }
        //发送更新商品消息
        sendMessageService.sendMessageToQueue(spu.getId(),SEND_QUEUE_UPDATE_TYPE);
    }

    @Cacheable(value = CacheConstants.CACHE_GOODS_SPU_ID,key = "#p0")
    @Override
    public GoodsVo querySpuBySpuId(Long spuId) {
     Spu spu=spuMapper.selectByPrimaryKey(spuId);
     SpuDetail spuDetail=spuDetailMapper.selectByPrimaryKey(spuId);
     List<Sku> skuList=  skuMapper.selectSkuBySpuId(spuId);
      GoodsVo goodsVo=new GoodsVo();
      BeanUtils.copyProperties(spu,goodsVo);
      goodsVo.setSpuDetail(spuDetail);
      goodsVo.setSkus(skuList);
        return goodsVo;
    }
}
